package com.joker.webSocket;

import com.joker.common.GlobalInteger;
import com.joker.common.GlobalMap;
import com.joker.entity.Chat;
import com.joker.entity.ChatSession;
import com.joker.entity.SessionAndUser;
import com.joker.service.ChatService;
import com.joker.service.ChatSessionService;
import com.joker.utils.AnsjUtil;
import com.joker.utils.JsonUtil;
import com.joker.utils.SpringContextUtil;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.ArrayList;
import java.util.List;
/**
 * <p>
 * webSocket 服务类
 * @Param userId 当前用户id
 * @Param sessionId 当前用户与对方用户的会话id
 * </p>
 *
 * @author joker
 * @since 2021-06-03
 */
@Component
@ServerEndpoint("/websocket/{userId}/{sessionId}")
public class WebSocketServer {

    private ChatSessionService chatSessionService;

    private ChatService chatService;

    private Session session;

    private Integer flag = 0;

    public void autoService(){
        //通过调用封装spring中的bean对象工具类的方法注入所需service
        if(this.chatSessionService == null){
            this.chatSessionService = SpringContextUtil.getBean(ChatSessionService.class);
        }
        if(this.chatService == null){
            this.chatService = SpringContextUtil.getBean(ChatService.class);
        }
    }

    @OnOpen
    public void onOpen(Session session, @PathParam("userId")String userId, @PathParam("sessionId")Integer sessionId){
        //建立会话连接时为用户创建对应的session
        this.session = session;
        if(GlobalMap.sessionPool.get(userId) != null){
            this.flag++;
        }
        //创建存储session信息的集合
        List<Object> sessionList = new ArrayList<>();
        sessionList.add(sessionId);
        sessionList.add(session);
        //将用户id和存有session信息的集合存入全局变量map中
        GlobalMap.sessionPool.put(userId, sessionList);
    }

    @OnClose
    public void onClose(){
        //断开连接时删除用户相应的session
        //获取请求map里的userId的第一个参数即当前用户的id
        String userId =  this.session.getRequestParameterMap().get("userId").get(0);
        GlobalMap.sessionPool.remove(userId);
        if(this.flag != 0){
            this.flag--;
        }else {
            GlobalInteger.onlineNumber--;
            System.out.println("用户"+userId+"退出登录,目前在线人数："+GlobalInteger.onlineNumber);
        }
        System.out.println("会话连接断开");
    }

    @OnMessage
    public void onMessage(String message){
        //获取请求map里的sessionId的第一个参数即当前用户对应的sessionId
        String sessionId = this.session.getRequestParameterMap().get("sessionId").get(0);
        if(sessionId == null){
            System.out.println("请求异常，sessionId为空");
            return;
        }
        //调用方法注入所需Service
        this.autoService();
        //获取session下的用户信息
        ChatSession chatSession = this.chatSessionService.findBySessionId(Integer.parseInt(sessionId));
        String userId = chatSession.getUserId();
        String toUserId = chatSession.getToUserId();
        Chat chat = new Chat();
        chat.setChatSend(userId);
        chat.setChatReceive(toUserId);
        chat.setChatContent(message);
        chat.setReadFlag(0);
        //将该记录入库
        if(this.chatService.save(chat) == 1){
            System.out.println("一条记录入库："+message);
        }else {
            System.out.println("聊天记录入库异常");
            return;
        }

        //判断对方用户和当前用户会话是否在线(对方是否和当前用户聊天)的条件
        List<Object> objectList = GlobalMap.sessionPool.get(toUserId);
        //判断对方用户和当前用户是否有连接记录的条件
        Integer id = null;

        try {
            id = chatSessionService.findByUserIdAndToUserId(toUserId,userId).getSessionId();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //开始判断
        //因为用户在线初始化时会调用onOpen方法，所以可以用会话在线判断对方是否在线
        //对方用户不在线
        if(objectList == null || objectList.isEmpty()){
            //封装对方用户与当前用是否聊过天的处理情况
            this.setChatSession(id,userId, toUserId);
        }else {
            //对方用户在线
            if(objectList.get(0).equals(id)){
                //对方用户正在和当前用户聊天
                chat.setChatDate(null);
                //向对方发送纯文本消息
                this.sendTextMessage(toUserId,JsonUtil.objectToJson(chat));
            }else {
                //封装对方用户与当前用是否聊过天的处理情况
                this.setChatSession(id,userId, toUserId);
                //封装好对方用户的会话信息列表
                List<SessionAndUser> sessionList = chatSessionService.findAllByUserId(toUserId);
                //发送封装好的会话信息列表
                this.sendTextMessage(toUserId, JsonUtil.objectToJson(sessionList));
            }
        }
    }

    //对方用户未与当前用户建立会话过，即数据库中未存在对方与当前用户的会话连接记录
    //新建连接记录入库
    public void setChatSession(Integer id,String userId,String toUserId){
        if(id == null || "".equals(id) || "null".equals(id)){
            //若对方从未和当前用户聊过天
            ChatSession tempSession = new ChatSession();
            tempSession.setToUserId(userId);
            tempSession.setUserId(toUserId);
            tempSession.setUnReadCount(1);
            this.chatSessionService.save(tempSession);
        }else {
            //更新未读的消息数
            this.chatSessionService.addUnReadCountByUserIdAndToUserId(toUserId,userId);
        }
    }

    //发送信息
    public void sendTextMessage(String toUserId, String message) {
        Session session = (Session)GlobalMap.sessionPool.get(toUserId).get(1);
        if (session != null) {
            try {
                session.getBasicRemote().sendText(message);
                System.out.println("发送成功");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


}
